﻿/*** MikeWare Framework ************************************
* This class is part of product of MikeWare.Framework.
* 
* Author      : Mike Cheers
* Mail        : mikecheers@126.com
* Create Date : 2018/9/14
* Summary     : 
* 
* 
* Modified By : 
* Date        : 
* Mail        : 
* Comment     : 
**************************************************************/

namespace MikeWare.Core.Algorithms
{
    using System;
    using System.Security.Cryptography;
    using System.Text;

    public static class EnAndDen
    {
        /// <summary>
        /// 系统缺省密钥
        /// </summary>
        private static string EncryptKeys;

        /// <summary>
        /// 构造方法
        /// </summary>
        static EnAndDen() { EncryptKeys = "MikeCheers.CoM"; }

        #region 使用 缺省密钥字符串 加密/解密string

        /// <summary>
        /// 使用缺省密钥字符串加密string
        /// </summary>
        /// <param name="original">明文</param>
        /// <returns>密文</returns>
        public static string Encrypt(string original)
        {
            return Encrypt(original, EncryptKeys);
        }
        /// <summary>
        /// 使用缺省密钥字符串解密string
        /// </summary>
        /// <param name="original">密文</param>
        /// <returns>明文</returns>
        public static string Decrypt(string original)
        {
            return Decrypt(original, EncryptKeys, System.Text.Encoding.Default);
        }

        #endregion

        #region 使用 给定密钥字符串 加密/解密string
        /// <summary>
        /// 使用给定密钥字符串加密string
        /// </summary>
        /// <param name="original">原始文字</param>
        /// <param name="key">密钥</param>
        /// <param name="encoding">字符编码方案</param>
        /// <returns>密文</returns>
        public static string Encrypt(string original, string key)
        {
            byte[] buff = System.Text.Encoding.Default.GetBytes(original);
            byte[] kb = System.Text.Encoding.Default.GetBytes(key);
            return Convert.ToBase64String(Encrypt(buff, kb));
        }
        /// <summary>
        /// 使用给定密钥字符串解密string
        /// </summary>
        /// <param name="original">密文</param>
        /// <param name="key">密钥</param>
        /// <returns>明文</returns>
        public static string Decrypt(string original, string key)
        {
            return Decrypt(original, key, System.Text.Encoding.Default);
        }

        /// <summary>
        /// 使用给定密钥字符串解密string,返回指定编码方式明文
        /// </summary>
        /// <param name="encrypted">密文</param>
        /// <param name="key">密钥</param>
        /// <param name="encoding">字符编码方案</param>
        /// <returns>明文</returns>
        public static string Decrypt(string encrypted, string key, Encoding encoding)
        {
            byte[] buff = Convert.FromBase64String(encrypted);
            byte[] kb = System.Text.Encoding.Default.GetBytes(key);
            return encoding.GetString(Decrypt(buff, kb));
        }
        #endregion

        #region 使用 缺省密钥字符串 加密/解密/byte[]
        /// <summary>
        /// 使用缺省密钥字符串解密byte[]
        /// </summary>
        /// <param name="encrypted">密文</param>
        /// <param name="key">密钥</param>
        /// <returns>明文</returns>
        public static byte[] Decrypt(byte[] encrypted)
        {
            byte[] key = System.Text.Encoding.Default.GetBytes(EncryptKeys);
            return Decrypt(encrypted, key);
        }
        /// <summary>
        /// 使用缺省密钥字符串加密
        /// </summary>
        /// <param name="original">原始数据</param>
        /// <param name="key">密钥</param>
        /// <returns>密文</returns>
        public static byte[] Encrypt(byte[] original)
        {
            byte[] key = System.Text.Encoding.Default.GetBytes(EncryptKeys);
            return Encrypt(original, key);
        }
        #endregion

        #region  使用 给定密钥 加密/解密/byte[]

        /// <summary>
        /// 生成MD5摘要
        /// </summary>
        /// <param name="original">数据源</param>
        /// <returns>摘要</returns>
        public static byte[] MakeMD5(byte[] original)
        {
            MD5CryptoServiceProvider hashmd5 = new MD5CryptoServiceProvider();
            byte[] keyhash = hashmd5.ComputeHash(original);
            hashmd5 = null;
            return keyhash;
        }


        /// <summary>
        /// 使用给定密钥加密
        /// </summary>
        /// <param name="original">明文</param>
        /// <param name="key">密钥</param>
        /// <returns>密文</returns>
        public static byte[] Encrypt(byte[] original, byte[] key)
        {
            TripleDESCryptoServiceProvider des = new TripleDESCryptoServiceProvider();
            des.Key = MakeMD5(key);
            des.Mode = CipherMode.ECB;

            return des.CreateEncryptor().TransformFinalBlock(original, 0, original.Length);
        }

        /// <summary>
        /// 使用给定密钥解密数据
        /// </summary>
        /// <param name="encrypted">密文</param>
        /// <param name="key">密钥</param>
        /// <returns>明文</returns>
        public static byte[] Decrypt(byte[] encrypted, byte[] key)
        {
            TripleDESCryptoServiceProvider des = new TripleDESCryptoServiceProvider();
            des.Key = MakeMD5(key);
            des.Mode = CipherMode.ECB;

            return des.CreateDecryptor().TransformFinalBlock(encrypted, 0, encrypted.Length);
        }

        #endregion

        public static string MD5Decrypt(string str)
        {
            return MD5Decrypt(str, 16);
        }

        public static string MD5Decrypt(string str, int code)
        {
            if (string.IsNullOrEmpty(str))
                return "";
            if (code == 16) //16位MD5加密（取32位加密的9~25字符）  
            {
                return System.Web.Security.FormsAuthentication.HashPasswordForStoringInConfigFile(str, "MD5").ToLower().Substring(8, 16);
            }
            else //32位加密  
            {
                return System.Web.Security.FormsAuthentication.HashPasswordForStoringInConfigFile(str, "MD5").ToLower();
            }
        }

        /// <summary>
        /// md5加密，不做大小写处理
        /// </summary>
        /// <param name="str"></param>
        /// <param name="code"></param>
        /// <returns></returns>
        public static string MD5En(string str)
        {
            return MD5En(str, 32);
        }

        /// <summary>
        /// md5加密，不做大小写处理
        /// </summary>
        /// <param name="str"></param>
        /// <param name="code"></param>
        /// <returns></returns>
        public static string MD5En(string str, int code)
        {
            if (string.IsNullOrEmpty(str))
                return "";
            if (code == 16) //16位MD5加密（取32位加密的9~25字符）
            {
                return System.Web.Security.FormsAuthentication.HashPasswordForStoringInConfigFile(str, "MD5").Substring(8, 16);
            }
            else //32位加密  
            {
                return System.Web.Security.FormsAuthentication.HashPasswordForStoringInConfigFile(str, "MD5");
            }
        }

        #region 取得MD5加密串
        /// 取得字符串的md5加密串 Mike Cheers 20120103添加
        /// <summary>
        /// 取得字符串的md5加密串
        /// </summary>
        /// <param name="str">原字符串</param>
        /// <param name="encodingString">编码集,如GB2312等</param>
        /// <returns></returns>
        static public string GetMD5String(string str, Encoding encoding)
        {
            MD5 md5 = new MD5CryptoServiceProvider();
            byte[] t = md5.ComputeHash(encoding.GetBytes(str));
            StringBuilder reString = new StringBuilder(32);
            for (int i = 0; i < t.Length; i++)
            {
                reString.Append(t[i].ToString("x").PadLeft(2, '0'));
            }
            return reString.ToString();
        }

        /// 取得字符串的md5加密串 Mike Cheers 20120103添加
        /// <summary>
        /// 取得字符串的md5加密串
        /// </summary>
        /// <param name="str">原字符串</param>
        /// <returns></returns>
        static public string GetMD5String(string str)
        {
            return GetMD5String(str, new UTF8Encoding(false));
        }

        /// 取得字符串的md5加密串 Blueice20111103添加
        /// Updated By Mike Cheers 20120103更新
        /// <summary>
        /// 取得字符串的md5加密串
        /// </summary>
        /// <param name="str">原字符串</param>
        /// <param name="encodingString">编码集,如GB2312等</param>
        /// <returns></returns>
        static public string GetMD5String(string str, string encodingString)
        {
            return GetMD5String(str, Encoding.GetEncoding(encodingString));
        }

        static public string GetMD5String(string str, int codePage)
        {
            return GetMD5String(str, Encoding.GetEncoding(codePage));
        }

        #endregion

        /// <summary>
        /// 基于Sha1的自定义加密字符串方法：输入一个字符串，返回一个由40个字符组成的十六进制的哈希散列（字符串）。
        /// </summary>
        /// <param name="str">要加密的字符串</param>
        /// <returns>加密后的十六进制的哈希散列（字符串）</returns>
        public static string Sha1(this string str)
        {
            return str.Sha1(Encoding.UTF8);
        }

        public static string Sha1(this string str, Encoding encoding)
        {
            var buffer = encoding.GetBytes(str);
            var data = SHA1.Create().ComputeHash(buffer);

            var sb = new StringBuilder();
            foreach (var t in data)
            {
                sb.Append(t.ToString("x2"));
            }

            return sb.ToString();
        }

        public static bool CheckMD5(string source, string target, int code)
        {
            return MD5Decrypt(source, code) == target.ToLower();
        }
    }
}
